package cn.iocoder.yudao.module.handguard.controller.admin.client;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.handguard.controller.admin.client.vo.*;
import cn.iocoder.yudao.module.handguard.controller.admin.homeone.vo.HomeOneUpdateReqVO;
import cn.iocoder.yudao.module.handguard.controller.admin.order.vo.MemberUserBaseVO;
import cn.iocoder.yudao.module.handguard.controller.admin.order.vo.OrderRespVO;
import cn.iocoder.yudao.module.handguard.controller.app.applicationrecord.vo.*;
import cn.iocoder.yudao.module.handguard.controller.app.user.vo.UserBaseVO;
import cn.iocoder.yudao.module.handguard.controller.app.wealthrecord.vo.WealthRecordRespVO;
import cn.iocoder.yudao.module.handguard.convert.applicationrecord.ApplicationRecordConvert;
import cn.iocoder.yudao.module.handguard.convert.order.OrderConvert;
import cn.iocoder.yudao.module.handguard.convert.user.MiniUserConvert;
import cn.iocoder.yudao.module.handguard.convert.wealthrecord.WealthRecordConvert;
import cn.iocoder.yudao.module.handguard.dal.dataobject.applicationdeductrecord.ApplicationDeductRecordDO;
import cn.iocoder.yudao.module.handguard.dal.dataobject.applicationrecord.ApplicationRecordDO;
import cn.iocoder.yudao.module.handguard.dal.dataobject.order.OrderDO;
import cn.iocoder.yudao.module.handguard.dal.dataobject.product.ProductDO;
import cn.iocoder.yudao.module.handguard.dal.dataobject.user.UserDO;
import cn.iocoder.yudao.module.handguard.dal.dataobject.wealthrecord.WealthRecordDO;
import cn.iocoder.yudao.module.handguard.dal.mysql.product.ProductMapper;
import cn.iocoder.yudao.module.handguard.dal.mysql.user.MiniUserMapper;
import cn.iocoder.yudao.module.handguard.enums.OrderFlowEnum;
import cn.iocoder.yudao.module.handguard.enums.OrderStatusEnum;
import cn.iocoder.yudao.module.handguard.service.applicationdeductrecord.ApplicationDeductRecordService;
import cn.iocoder.yudao.module.handguard.service.applicationrecord.ApplicationRecordService;
import cn.iocoder.yudao.module.handguard.service.order.OrderService;
import cn.iocoder.yudao.module.handguard.service.product.ProductService;
import cn.iocoder.yudao.module.handguard.service.user.MiniUserService;
import cn.iocoder.yudao.module.handguard.service.wealthrecord.WealthRecordService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.BeanUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;

/**
 * @author: liuweijun
 * @since: 2023/9/11 17:12
 * @description:
 */

@Tag(name = "管理后台 - 客户池、业务员、权证相关")
@RestController
@RequestMapping("/hutai/client")
@Validated
public class ClientController {


    @Resource
    private MiniUserService miniUserService;

    @Resource
    private OrderService orderService;

    @Resource
    private ProductService productService;

    @Resource
    private WealthRecordService wealthRecordService;

    @Resource
    private ApplicationDeductRecordService deductRecordService;

    @Resource
    private MiniUserMapper miniUserMapper;

    @Resource
    private ApplicationRecordService applicationRecordService;

    @GetMapping("/page")
    @Operation(summary = "获得客户用户分页")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<PageResult<UserBaseVO>> getUserPage(@Valid UserPageReqVO pageVO) {
        //pageVO.setUserType("1");
        //pageVO.setStatus(0);
        PageResult<UserDO> pageResult = miniUserService.getUserPage(pageVO);
        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(PageResult.empty());
        }
        return success(MiniUserConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/applyPage")
    @Operation(summary = "用户贷款记录分页")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<PageResult<ApplyRecordDO>> getApplicationRecordListPage(ApplyRecordPageReqVO pageVO) {
        PageResult<ApplyRecordDO> pageResult = applicationRecordService.getApplicationRecordListPage(pageVO);
        return success(pageResult);
    }

    @GetMapping("/applyPages")
    @Operation(summary = "根据角色查询用户贷款记录")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<PageResult<ApplyRecordDO>> getApplicationRecordListByRolePage(ApplyRecordPageReqVO pageVO) {
        //当前用户id
        Long userId = getLoginUser().getId();
        //当前用户id
        PageResult<ApplyRecordDO> pageResult = applicationRecordService.getApplicationRecordListByRolePage(pageVO,userId);
        return success(pageResult);
    }

    @GetMapping("/getUserInfo")
    @Operation(summary = "获取个人信息")
    @Parameter(name = "id", description = "id", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<MemberUserBaseVO> getOrderUserInfo(@RequestParam("id") Long id) {
        MemberUserBaseVO baseVO = miniUserService.getUserInfo(id);
        baseVO.setUserId(id);
        return success(baseVO);
    }

    @GetMapping("/user/forbidden")
    @Operation(summary = "客户池-禁用用户")
    @Parameter(name = "id", description = "id", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('client:user:update')")
    public CommonResult<Integer> forbidden(@RequestParam("id") Long id) {
        UserDO userDO = miniUserMapper.selectById(id);
        userDO.setStatus(1);
        int result = miniUserMapper.updateById(userDO);
        return success(result);
    }

    @GetMapping("/user/delete")
    @Operation(summary = "客户池-删除用户")
    @Parameter(name = "id", description = "id", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('client:user:update')")
    public CommonResult<Integer> delete(@RequestParam("id") Long id) {
        int  result =miniUserMapper.deleteById(id);
        return success(result);
    }


    @GetMapping("/getAgentList")
    @Operation(summary = "业务员列表")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<List<UserBaseVO>> getAgentList() {
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getUserType,"2");
        queryWrapper.eq(UserDO::getStatus,0);
        List<UserDO> userDOList = miniUserMapper.selectList(queryWrapper);
        return success(MiniUserConvert.INSTANCE.convertList(userDOList));
    }

    @GetMapping("/getWarrantList")
    @Operation(summary = "权证员列表")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<List<UserBaseVO>> getWarrantList() {
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getUserType,"3");
        queryWrapper.eq(UserDO::getStatus,0);
        List<UserDO> userDOList = miniUserMapper.selectList(queryWrapper);
        return success(MiniUserConvert.INSTANCE.convertList(userDOList));
    }


    @PostMapping("/allocationAgent")
    @Operation(summary = "业务员")
    @PreAuthorize("@ss.hasPermission('client:user:update')")
    public CommonResult<Boolean> allocationAgent(@Valid @RequestBody UserAllocationReqVo reqVo) {
        miniUserService.updateUserAllocationAgent(reqVo);
        return success(true);
    }

    @PostMapping("/allocationWarrant")
    @Operation(summary = "分配权证员")
    @PreAuthorize("@ss.hasPermission('client:user:update')")
    public CommonResult<Boolean> allocationWarrant(@Valid @RequestBody UserAllocationReqVo reqVo) {
        miniUserService.updateUserAllocationWarrant(reqVo);
        return success(true);
    }

    @PostMapping("/cancelAllocationAgent")
    @Operation(summary = "取消分配业务员")
    @PreAuthorize("@ss.hasPermission('client:user:update')")
    public CommonResult<Boolean> cancelAllocationAgent(@Valid @RequestBody UserAllocationReqVo reqVo) {
        miniUserService.cancelAllocationAgent(reqVo);
        return success(true);
    }

    @PostMapping("/cancelAllocationWarrant")
    @Operation(summary = "取消分配权证员")
    @PreAuthorize("@ss.hasPermission('client:user:update')")
    public CommonResult<Boolean> cancelAllocationWarrant(@Valid @RequestBody UserAllocationReqVo reqVo) {
        miniUserService.cancelAllocationWarrant(reqVo);
        return success(true);
    }


    @GetMapping("/list")
    @Operation(summary = "用户-贷款申请记录")
    @Parameter(name = "userId", description = "用户id", required = true, example = "1")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<List<OrderRespVO>> getOrderList(@RequestParam("userId") Long userId) {
        List<OrderDO> list = orderService.getOrderListByUserId(userId);
        return success(OrderConvert.INSTANCE.convertList(list));
    }


    @PostMapping("/addUsers")
    @Operation(summary = "新增业务员、权证员")
    @PreAuthorize("@ss.hasPermission('client:user:create')")
    public CommonResult<Boolean> addSalesman(@Valid @RequestBody UserAddReqVo reqVo) {
        miniUserService.addSalesman(reqVo);
        return success(true);
    }

    @PostMapping("/salesmanAddUser")
    @Operation(summary = "业务员-新增用户")
    public CommonResult<Boolean> salesmanAddUser(@Valid @RequestBody UserAddReqsVo reqVo) {
        miniUserService.salesmanAddUser(reqVo);
        return success(true);
    }



    @GetMapping("/getHeRecommend")
    @Operation(summary = "他的推荐")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<List<UserBaseVO>> getHeRecommend(Long userId) {
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getReferrer,userId);
        List<UserDO> userDOList = miniUserMapper.selectList(queryWrapper);
        return success(MiniUserConvert.INSTANCE.convertList(userDOList));
    }

    @GetMapping("/getMiRecommend")
    @Operation(summary = "我的推荐人")
    @PreAuthorize("@ss.hasPermission('client:user:query')")
    public CommonResult<List<UserBaseVO>> getMiRecommend(Long userId) {
        LambdaQueryWrapper<UserDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserDO::getId,userId);
        UserDO userDO = miniUserMapper.selectOne(queryWrapper);

        LambdaQueryWrapper<UserDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserDO::getId,userDO.getReferrer());
        List<UserDO> userDOList = miniUserMapper.selectList(wrapper);
        return success(MiniUserConvert.INSTANCE.convertList(userDOList));
    }


    @GetMapping("/getWealthRecordList")
    @Operation(summary = "用户-财富值明细记录列表")
    @Parameter(name = "userId", description = "用户id", required = true, example = "1")
    public CommonResult<UserWealthRecordRespVO> getWealthRecordList(Long userId) {
        UserWealthRecordRespVO respVO = new UserWealthRecordRespVO();
        List<WealthRecordDO> list = wealthRecordService.getWealthRecordList(userId);
        List<WealthRecordRespVO> respVOList = WealthRecordConvert.INSTANCE.convertList(list);
        UserDO userDO = miniUserMapper.selectById(userId);
        respVO.setWealth(userDO.getWealthValue());
        respVO.setVoList(respVOList);
        return success(respVO);
    }


    @GetMapping("/export-excel")
    @Operation(summary = "导出用户申请贷款表 Excel")
    @PreAuthorize("@ss.hasPermission('client:user:export')")
    @OperateLog(type = EXPORT)
    public void exportApplicationRecordExcel(@Valid ApplyRecordPageReqVO exportReqVO,
                                             HttpServletResponse response) throws IOException {
        List<ApplyRecordDO> list = applicationRecordService.getApplicationRecordList(exportReqVO);
        List<ApplicationRecordExcelVO> datas = new ArrayList<>();
        if (list.size()>0){
            for (ApplyRecordDO recordDO : list){
                ApplicationRecordExcelVO recordExcelVO = new ApplicationRecordExcelVO();
                BeanUtils.copyProperties(recordDO, recordExcelVO);
                ProductDO productDO = productService.getProduct(Long.valueOf(recordDO.getProductId()));
                if (productDO !=null){
                    recordExcelVO.setProductName(productDO.getProductName());
                }

                //查询提成
                ApplicationDeductRecordDO deductRecordDO = deductRecordService.getApplicationDeductRecordListByOrderId(recordDO.getId());
                //已结单直接显示
                if (deductRecordDO!=null){
                    if(recordDO.getApplyState().equals("3")){
                        recordExcelVO.setDirectProfit(deductRecordDO.getDirectProfit()+ "元");
                    }else {
                        if (deductRecordDO.getDirectProfit()!=null){
                            if (deductRecordDO.getDeductType().equals("0")){
                                recordExcelVO.setDirectProfit(deductRecordDO.getDirectProfit()+ "元");
                            }else {
                                recordExcelVO.setDirectProfit(deductRecordDO.getDirectProfit()+ "%");
                            }
                        }
                    }
                }
                recordExcelVO.setOrderId(String.valueOf(recordDO.getId()));
                recordExcelVO.setIssuanceTimeStr(LocalDateTimeUtils.getDateTimeFormat(recordDO.getIssuanceTime()));
                recordExcelVO.setPracticalTimeStr(LocalDateTimeUtils.getDateTimeFormat(recordDO.getPracticalTime()));
                recordExcelVO.setApplyStateName(OrderStatusEnum.valueOf(Integer.valueOf(recordDO.getApplyState())).getStatusName());
                recordExcelVO.setFlowName(OrderFlowEnum.valueOf(Integer.valueOf(recordDO.getFlowN())).getStatusName());
                datas.add(recordExcelVO);
            }
        }
        // 导出 Excel
        ExcelUtils.write(response, "用户贷款申请表.xls", "数据", ApplicationRecordExcelVO.class, datas);
    }

}
